#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2020-2023 Alibaba Group Holding Limited.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from collections.abc import Iterable
from typing import Any
from typing import Dict
from typing import List
from typing import Tuple
from typing import Union
from typing import overload

from vineyard.core.client import Client

class ObjectID:
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, id: int) -> None: ...
    @overload
    def __init__(self, id: str) -> None: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: "ObjectID") -> bool: ...
    def __hash__(self) -> int: ...
    @staticmethod
    def from_uri(uri: str) -> "ObjectID": ...

class ObjectName:
    def __init__(self, name: str) -> None: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: "ObjectName") -> bool: ...
    def __hash__(self) -> int: ...
    @property
    def uri(self) -> str: ...
    @staticmethod
    def from_uri(uri: str) -> "ObjectName": ...

class ObjectMeta:
    def __init__(self, *args, global_: bool = False, **kwargs) -> None: ...
    @property
    def _client(self) -> Union["IPCClient", "RPCClient"]: ...
    @property
    def id(self) -> ObjectID: ...
    @property
    def signature(self) -> int: ...
    @property
    def typename(self) -> str: ...
    @property
    def nbytes(self) -> int: ...
    @property
    def instance_id(self) -> int: ...
    @property
    def islocal(self) -> bool: ...
    @property
    def isglobal(self) -> bool: ...
    def set_global(self, global_: bool = True) -> None: ...
    def __contains__(self, key: str) -> bool: ...
    def __getitem__(
        self, key: str
    ) -> Union["ObjectMeta", bool, int, float, str, Any]: ...
    def get(self, key: str) -> Union["ObjectMeta", bool, int, float, str, Any]: ...
    def get_member(self, key: str) -> "ObjectMeta": ...
    def get_buffer(self, key: ObjectID) -> memoryview: ...
    def __setitem__(
        self,
        key: str,
        value: Union["ObjectMeta", bool, int, float, str, List, Dict, Any],
    ) -> None: ...
    def add_member(
        self, key: str, member: Union["ObjectMeta", "ObjectID", "Object"]
    ) -> None: ...
    @property
    def memory_usage(self) -> int: ...
    def memory_usage_details(
        self, pretty: bool = True
    ) -> Dict[str, Union[Dict, int]]: ...
    @property
    def timestamp(self) -> int: ...
    @property
    def labels(self) -> Dict[str, str]: ...
    def label(self, key: str) -> str: ...
    def reset_key(self) -> None: ...
    def reset_signature(self) -> None: ...
    def items(
        self,
    ) -> List[Tuple[str, Union["ObjectMeta", bool, int, float, str, Any]]]: ...
    def __repr__(self) -> str: ...

class Object:
    @property
    def id(self) -> ObjectID: ...
    @property
    def signature(self) -> int: ...
    @property
    def meta(self) -> ObjectMeta: ...
    @property
    def nbytes(self) -> int: ...
    @property
    def typename(self) -> str: ...
    def member(self, key: str) -> "Object": ...
    def __getitem__(self, key: str) -> "Object": ...
    @property
    def islocal(self) -> bool: ...
    @property
    def ispersist(self) -> bool: ...
    @property
    def isglobal(self) -> bool: ...

class ObjectBuilder:
    def seal(self, client: Client) -> "Object": ...
    @property
    def issealed(self) -> bool: ...

class Blob(Object):
    @property
    def size(self) -> int: ...
    @property
    def is_empty(self) -> bool: ...
    @staticmethod
    def empty() -> "Blob": ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterable[int]: ...
    def __getitem__(self, key: int) -> int: ...
    @property
    def address(self) -> int: ...
    @property
    def buffer(self) -> memoryview: ...

class BlobBuilder(ObjectBuilder):
    @property
    def id(self) -> ObjectID: ...
    @property
    def size(self) -> int: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterable[int]: ...
    def __getitem__(self, key: int) -> int: ...
    @overload
    def __setitem__(self, key: int, value: int) -> None: ...
    @overload
    def __setitem__(self, key: slice, value: Union[bytes, memoryview]) -> None: ...
    def abort(self) -> None: ...
    @overload
    def copy(self, offset: int, ptr: int, size: int) -> None: ...
    @overload
    def copy(self, offset: int, buffer: Union[bytes, memoryview]) -> None: ...
    @property
    def address(self) -> int: ...
    @property
    def buffer(self) -> memoryview: ...

class RemoteBlob(Object):
    @property
    def id(self) -> ObjectID: ...
    @property
    def instance_id(self) -> int: ...
    @property
    def size(self) -> int: ...
    @property
    def allocated_size(self) -> int: ...
    @property
    def is_empty(self) -> bool: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterable[int]: ...
    def __getitem__(self, key: int) -> int: ...
    @property
    def address(self) -> int: ...
    @property
    def buffer(self) -> memoryview: ...

class RemoteBlobBuilder:
    def __init__(self, size: int) -> None: ...
    @property
    def size(self) -> int: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterable[int]: ...
    def __getitem__(self, key: int) -> int: ...
    @overload
    def __setitem__(self, key: int, value: int) -> None: ...
    @overload
    def __setitem__(self, key: slice, value: Union[bytes, memoryview]) -> None: ...
    def abort(self) -> None: ...
    @overload
    def copy(self, offset: int, ptr: int, size: int) -> None: ...
    @overload
    def copy(self, offset: int, buffer: Union[bytes, memoryview]) -> None: ...
    @property
    def address(self) -> int: ...
    @property
    def buffer(self) -> memoryview: ...

class InstanceStatus:
    @property
    def instance_id(self) -> int: ...
    @property
    def deployment(self) -> str: ...
    @property
    def memory_usage(self) -> int: ...
    @property
    def memory_limit(self) -> int: ...
    @property
    def deferred_requests(self) -> int: ...
    @property
    def ipc_connections(self) -> int: ...
    @property
    def rpc_connections(self) -> int: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...

class ClientBase:
    @overload
    def create_metadata(
        self, metadata: Union[ObjectMeta, List[ObjectMeta]]
    ) -> Union[ObjectMeta, List[ObjectMeta]]: ...
    @overload
    def create_metadata(
        self, metadata: Union[ObjectMeta, List[ObjectMeta]], instance_id: int
    ) -> Union[ObjectMeta, List[ObjectMeta]]: ...
    def delete(
        self,
        object: Union[ObjectID, Object, ObjectMeta, List[ObjectID]],
        force: bool = False,
        deep: bool = True,
        memory_trim: bool = False,
    ) -> None: ...
    def create_stream(self, id: ObjectID) -> None: ...
    def open_stream(self, id: ObjectID, mode: str) -> None: ...
    def push_chunk(self, stream_id: ObjectID, chunk: ObjectID) -> None: ...
    def next_chunk_id(self, stream_id: ObjectID) -> ObjectID: ...
    def next_chunk_meta(self, stream_id: ObjectID) -> ObjectMeta: ...
    def next_chunk(self, stream_id: ObjectID) -> Object: ...
    def stop_stream(self, stream_id: ObjectID, failed: bool) -> None: ...
    def drop_stream(self, stream_id: ObjectID) -> None: ...
    def persist(self, object: Union[ObjectID, Object, ObjectMeta]) -> None: ...
    def exists(self, object: ObjectID) -> bool: ...
    @overload
    def shallow_copy(self, object_id: ObjectID) -> ObjectID: ...
    @overload
    def shallow_copy(
        self, object_id: ObjectID, extra_metadata: Dict[str, Any]
    ) -> ObjectID: ...
    def list_names(
        self, pattern: str, regex: bool = False, limit: int = 5
    ) -> List[str]: ...
    def put_name(
        self, object: Union[ObjectID, ObjectMeta, Object], name: str
    ) -> None: ...
    def get_name(self, name: str, wait: bool = False) -> ObjectID: ...
    def drop_name(self, name: str) -> None: ...
    def sync_meta(self) -> None: ...
    def migrate(self, object_id: ObjectID) -> ObjectID: ...
    def clear(self) -> None: ...
    @overload
    def label(self, object_id: ObjectID, key: str, value: str) -> None: ...
    @overload
    def label(self, object_id: ObjectID, labels: Dict[str, str]) -> None: ...
    def evict(self, objects: List[ObjectID]) -> None: ...
    def load(self, objects: List[ObjectID], pin: bool = False) -> None: ...
    def unpin(self, objects: List[ObjectID]) -> None: ...
    def reset(self) -> None: ...
    @property
    def connected(self) -> bool: ...
    @property
    def instance_id(self) -> int: ...
    @property
    def meta(self) -> Dict[int, Dict[str, any]]: ...
    @property
    def status(self) -> InstanceStatus: ...
    @property
    def ipc_socket(self) -> str: ...
    @property
    def rpc_endpoint(self) -> str: ...
    @property
    def version(self) -> str: ...

class IPCClient(ClientBase):
    def get(
        self,
        object_id: ObjectID = None,
        name: str = None,
        resolver: "ResolverContext" = None,
        fetch: bool = False,
        **kw,
    ): ...
    def put(
        self,
        value: Any,
        builder: "BuilderContext" = None,
        persist: bool = False,
        name: str = None,
        **kwargs,
    ): ...
    def create_blob(
        self, size: Union[int, List[int]]
    ) -> Union[BlobBuilder, List[BlobBuilder]]: ...
    def create_empty_blob(self) -> BlobBuilder: ...
    def get_blob(self, object_id: ObjectID, unsafe: bool = False) -> Blob: ...
    def get_blobs(
        self, object_ids: List[ObjectID], unsafe: bool = False
    ) -> List[Blob]: ...
    def get_object(
        self, object_id: ObjectID, sync_remote: bool = True, fetch: bool = False
    ) -> Object: ...
    def get_objects(
        self, object_ids: List[ObjectID], sync_remote: bool = True
    ) -> List[Object]: ...
    def get_meta(
        self, object_id: ObjectID, sync_remote: bool = False, fetch: bool = False
    ) -> ObjectMeta: ...
    def get_metas(
        self, object_ids: List[ObjectID], sync_remote: bool = False
    ) -> List[ObjectMeta]: ...
    def list_objects(
        self, pattern: str, regex: bool = False, limit: int = 5
    ) -> List[ObjectID]: ...
    def list_metadatas(
        self, pattern: str, regex: bool = False, limit: int = 5, nobuffer: bool = False
    ) -> List[ObjectMeta]: ...
    def new_buffer_chunk(self, stream: ObjectID, size: int) -> memoryview: ...
    def next_buffer_chunk(self, stream: ObjectID) -> memoryview: ...
    def allocated_size(self, object_id: Union[Object, ObjectID]) -> int: ...
    def is_shared_memory(self, pointer: int) -> bool: ...
    def find_shared_memory(self, pointer: int) -> ObjectID: ...
    def close(self) -> None: ...
    def fork(self) -> "IPCClient": ...
    def __enter__(self) -> "IPCClient": ...
    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: ...

class RPCClient(ClientBase):
    def get(
        self,
        object_id: ObjectID = None,
        name: str = None,
        resolver: "ResolverContext" = None,
        fetch: bool = False,
        **kw,
    ): ...
    def put(
        self,
        value: Any,
        builder: "BuilderContext" = None,
        persist: bool = False,
        name: str = None,
        **kwargs,
    ): ...
    def create_remote_blob(
        self, blob_builder: Union[RemoteBlobBuilder, List[RemoteBlobBuilder]]
    ) -> Union[ObjectMeta, List[ObjectMeta]]: ...
    def get_remote_blob(
        self, object_id: ObjectID, unsafe: bool = False
    ) -> RemoteBlob: ...
    def get_remote_blobs(
        self, object_ids: List[ObjectID], unsafe: bool = False
    ) -> List[RemoteBlob]: ...
    def get_object(self, object_id: ObjectID, sync_remote: bool = True) -> Object: ...
    def get_objects(
        self, object_ids: List[ObjectID], sync_remote: bool = True
    ) -> List[Object]: ...
    def get_meta(
        self, object_id: ObjectID, sync_remote: bool = False
    ) -> ObjectMeta: ...
    def get_metas(
        self, object_ids: List[ObjectID], sync_remote: bool = False
    ) -> List[ObjectMeta]: ...
    def list_objects(
        self, pattern: str, regex: bool = False, limit: int = 5
    ) -> List[ObjectID]: ...
    def list_metadatas(
        self, pattern: str, regex: bool = False, limit: int = 5
    ) -> List[ObjectMeta]: ...
    def close(self) -> None: ...
    def fork(self) -> "RPCClient": ...
    @property
    def remote_instance_id(self) -> int: ...
    def __enter__(self) -> "RPCClient": ...
    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: ...

@overload
def connect(
    target: None = None, *, username: str = "", password: str = ""
) -> IPCClient: ...
@overload
def connect(
    socket: str = "", *, username: str = "", password: str = ""
) -> IPCClient: ...
@overload
def connect(
    host: str,
    port: Union[int, str],
    session_id: int = 0,
    *,
    username: str = "",
    password: str = "",
) -> RPCClient: ...
@overload
def connect(
    endpoint: Tuple[str, Union[int, str]],
    session_id: int = 0,
    *,
    username: str = "",
    password: str = "",
) -> RPCClient: ...
